package com.school.sports.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.school.sports.entity.Schedule;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 赛程服务接口
 */
public interface ScheduleService extends IService<Schedule> {

    /**
     * 分页查询赛程列表
     * @param page 分页对象
     * @param queryWrapper 查询条件
     * @return 分页结果
     */
    IPage<Schedule> page(Page<Schedule> page, com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Schedule> queryWrapper);

    /**
     * 根据ID查询赛程详情（包含项目、场地、裁判信息）
     * @param id 赛程ID
     * @return 赛程详情
     */
    Schedule getScheduleWithDetails(Long id);

    /**
     * 创建赛程
     * @param schedule 赛程信息
     * @return 创建结果
     */
    boolean createSchedule(Schedule schedule);

    /**
     * 更新赛程信息
     * @param schedule 赛程信息
     * @return 更新结果
     */
    boolean updateSchedule(Schedule schedule);

    /**
     * 删除赛程
     * @param id 赛程ID
     * @return 删除结果
     */
    boolean deleteSchedule(Long id);

    /**
     * 更新赛程状态
     * @param id 赛程ID
     * @param status 新状态
     * @return 更新结果
     */
    boolean updateScheduleStatus(Long id, String status);

    /**
     * 开始比赛
     * @param id 赛程ID
     * @return 操作结果
     */
    boolean startSchedule(Long id);

    /**
     * 结束比赛
     * @param id 赛程ID
     * @return 操作结果
     */
    boolean endSchedule(Long id);

    /**
     * 延期比赛
     * @param id 赛程ID
     * @param newStartTime 新开始时间
     * @param newEndTime 新结束时间
     * @return 操作结果
     */
    boolean postponeSchedule(Long id, LocalDateTime newStartTime, LocalDateTime newEndTime);

    /**
     * 取消比赛
     * @param id 赛程ID
     * @return 操作结果
     */
    boolean cancelSchedule(Long id);

    /**
     * 检查场地时间冲突
     * @param venueId 场地ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param excludeId 排除的赛程ID（用于更新时检查）
     * @return 是否有冲突
     */
    boolean checkVenueTimeConflict(Integer venueId, LocalDateTime startTime, LocalDateTime endTime, Long excludeId);

    /**
     * 检查裁判时间冲突
     * @param refereeId 裁判ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param excludeId 排除的赛程ID（用于更新时检查）
     * @return 是否有冲突
     */
    boolean checkRefereeTimeConflict(Long refereeId, LocalDateTime startTime, LocalDateTime endTime, Long excludeId);

    /**
     * 根据项目ID查询赛程列表
     * @param projectId 项目ID
     * @return 赛程列表
     */
    List<Schedule> getSchedulesByProjectId(Long projectId);

    /**
     * 根据场地ID查询赛程列表
     * @param venueId 场地ID
     * @return 赛程列表
     */
    List<Schedule> getSchedulesByVenueId(Integer venueId);

    /**
     * 根据裁判ID查询赛程列表
     * @param refereeId 裁判ID
     * @return 赛程列表
     */
    List<Schedule> getSchedulesByRefereeId(Long refereeId);

    /**
     * 根据状态查询赛程列表
     * @param status 赛程状态
     * @return 赛程列表
     */
    List<Schedule> getSchedulesByStatus(String status);

    /**
     * 查询指定日期范围内的赛程
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 赛程列表
     */
    List<Schedule> getSchedulesByDateRange(LocalDateTime startDate, LocalDateTime endDate);

    /**
     * 查询今日赛程
     * @return 今日赛程列表
     */
    List<Schedule> getTodaySchedules();

    /**
     * 查询本周赛程
     * @return 本周赛程列表
     */
    List<Schedule> getWeekSchedules();

    /**
     * 查询即将开始的赛程（未来24小时内）
     * @return 即将开始的赛程列表
     */
    List<Schedule> getUpcomingSchedules();

    /**
     * 统计各种状态的赛程数量
     * @return 统计结果Map，key为状态，value为数量
     */
    java.util.Map<String, Long> getScheduleStatusStatistics();

    /**
     * 获取所有赛程状态
     * @return 赛程状态列表
     */
    List<String> getAllScheduleStatuses();

    /**
     * 分配裁判
     * @param scheduleId 赛程ID
     * @param refereeId 裁判ID
     * @return 分配结果
     */
    boolean assignReferee(Long scheduleId, Long refereeId);

    /**
     * 更换裁判
     * @param scheduleId 赛程ID
     * @param newRefereeId 新裁判ID
     * @return 更换结果
     */
    boolean changeReferee(Long scheduleId, Long newRefereeId);

    /**
     * 检查场地是否可用
     * @param venueId 场地ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 是否可用
     */
    boolean isVenueAvailable(Integer venueId, LocalDateTime startTime, LocalDateTime endTime);

    /**
     * 检查裁判是否可用
     * @param refereeId 裁判ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 是否可用
     */
    boolean isRefereeAvailable(Long refereeId, LocalDateTime startTime, LocalDateTime endTime);
}